package judesart.app.client.ui.admin.gallery;

import java.util.ArrayList;
import java.util.List;

import judesart.app.client.controller.ArtworkController;
import judesart.app.client.controller.ArtworkControllerAsync;
import judesart.app.client.controller.GalleryController;
import judesart.app.client.controller.GalleryControllerAsync;
import judesart.app.client.layout.MainLayout;
import judesart.app.client.widget.TopInfo;
import judesart.app.domain.Room;
import judesart.app.domain.RoomArtwork;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.MemoryProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.ListView;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextArea;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.FormPanel.LabelAlign;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Image;

public class RoomDetailsPanel extends Composite {
    private final List<RoomArtwork> artworks = new ArrayList<RoomArtwork>();
    private final ListLoader<ListLoadResult<RoomArtwork>> loader;
    private Room room;

    ArtworkControllerAsync artworkController = GWT.create(ArtworkController.class);
    GalleryControllerAsync galleryController = GalleryController.Util.getInstance();
    private final TextField<String> txtfldName;
    private final TextArea txtrDescription;
    private final GalleryDetailsPanel parent;
    private final ListView<BeanModel> artworksListView;

    public RoomDetailsPanel(GalleryDetailsPanel parent) {
        this.parent = parent;
        room = new Room();

        ContentPanel cntntpnlRoom = new ContentPanel();
        cntntpnlRoom.setHeading("Room");

        MemoryProxy<List<RoomArtwork>> proxy = new MemoryProxy<List<RoomArtwork>>(artworks);
        loader = new BaseListLoader<ListLoadResult<RoomArtwork>>(proxy, new BeanModelReader());
        ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
        loader.load();

        HorizontalPanel horizontalPanel = new HorizontalPanel();

        FormPanel formPanel = new FormPanel();
        formPanel.setLabelSeparator("");
        formPanel.setLabelAlign(LabelAlign.TOP);
        formPanel.setHeaderVisible(false);
        formPanel.setBorders(false);
        formPanel.setBodyBorder(false);

        txtfldName = new TextField<String>();
        formPanel.add(txtfldName, new FormData("100%"));
        txtfldName.setFieldLabel("Name");

        txtrDescription = new TextArea();
        txtrDescription.setHeight("164px");
        formPanel.add(txtrDescription, new FormData("100%"));
        txtrDescription.setFieldLabel("Description");

        ButtonBar buttons = new ButtonBar();
        buttons.setAlignment(HorizontalAlignment.RIGHT);
        buttons.setMinButtonWidth(80);

        Button btnSave = new Button("Save");
        btnSave.addListener(Events.Select, new Listener<ButtonEvent>() {
            public void handleEvent(ButtonEvent e) {
                save();
            }
        });
        buttons.add(btnSave);

        Button btnDelete = new Button("Delete");
        btnDelete.addListener(Events.Select, new Listener<ButtonEvent>() {
            public void handleEvent(ButtonEvent e) {
                delete();
            }
        });
        buttons.add(btnDelete);
        Button btnBack = new Button("Back");
        btnBack.addListener(Events.Select, new Listener<ButtonEvent>() {
            public void handleEvent(ButtonEvent e) {
                back();
            }
        });
        buttons.add(btnBack);
        formPanel.setSize("285px", "450px");
        horizontalPanel.add(formPanel);

        VerticalPanel verticalPanel = new VerticalPanel();
        verticalPanel.setHeight("395px");

        artworksListView = new ListView<BeanModel>(store) {
            @Override
            protected BeanModel prepareData(BeanModel model) {
                RoomArtwork g = model.getBean();
                Log.debug(" > [" + g.getArtworkId() + "]:["
                        + g.getMainImageId() + "]");
                return model;
            }
        };
        artworksListView.setLoadingText("loading...");
        artworksListView.setBorders(false);
        artworksListView.setSize("479px", "456px");
        artworksListView.setTemplate(getTemplate());
        artworksListView.setItemSelector("div.thumb-wrap");
        artworksListView.getSelectionModel().addListener(
                Events.SelectionChange,
                new Listener<SelectionChangedEvent<BeanModel>>() {
                    public void handleEvent(SelectionChangedEvent<BeanModel> be) {
                        onSelectionChanged(be);
                    }
                });

        verticalPanel.add(artworksListView);
        verticalPanel.add(buttons);
        horizontalPanel.add(verticalPanel);
        cntntpnlRoom.add(horizontalPanel);
        cntntpnlRoom.setBorders(false);
        cntntpnlRoom.setSize("798px", "483px");
        cntntpnlRoom.setBodyBorder(false);
        cntntpnlRoom.setHeaderVisible(false);
        initComponent(cntntpnlRoom);
    }

    private void back() {
        parent.showGallery();
    }

    private void save() {
        room.setDescription(txtrDescription.getValue());
        room.setName(txtfldName.getValue());
        if (room.getKey() == null) {
            addRoomToGalleryAsync();
        } else {
            updateRoomAsync();
        }
    }

    private void updateRoomAsync() {
        Log.debug(" > update room [" + room.getName() + "]");
        galleryController.updateRoom(room, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable caught) {
                TopInfo.display("Error", "Unable to update room");
                Log.error("Unable to update room", caught);
            }

            @Override
            public void onSuccess(Void result) {
                TopInfo.display("Info", "Room updated");
                MainLayout.getInstance().refreshMenu();
            }
        });
    }

    private void addRoomToGalleryAsync() {
        galleryController.addRoomToGallery(parent.getGallery().getId(), room,
                new AsyncCallback<Room>() {

                    @Override
                    public void onSuccess(Room result) {
                        setRoom(result);
                        parent.getGallery().getRooms().add(result);
                        TopInfo.display("Info", "Room created");
                        MainLayout.getInstance().refreshMenu();
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        TopInfo.display("Error",
                                "Unable to add room to gallery");
                        Log.error("Unable to add room to gallery", caught);
                    }
                });
    }

    private void delete() {
        if (room.getKey() == null) {
            back();
        }
        galleryController.deleteRoom(parent.getGallery().getId(),
                room.getKey(), new AsyncCallback<Void>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        TopInfo.display("Error", "Unable to delete room");
                        Log.error("Unable to delete room", caught);
                    }

                    @Override
                    public void onSuccess(Void result) {
                        TopInfo.display("Info", "Room deleted");
                        parent.getGallery().getRooms().remove(room);
                        MainLayout.getInstance().refreshMenu();
                        open(null);
                        back();
                    }
                });
    }

    private void setRoom(Room room) {
        this.room = room;
        artworks.clear();
        if (room.getArtworks() != null) {
            artworks.addAll(room.getArtworks());
        }
        loader.load();
        showDetails();
    }

    private void showDetails() {
        txtfldName.setValue(room.getName());
        txtrDescription.setValue(room.getDescription());
    }

    protected void open(Room room) {
        if (room == null) {
            room = new Room();
        }
        setRoom(room);
    }

    private native String getTemplate() /*-{
        return ['<tpl for=".">', 
        '<div style="border: 1px solid #FFFFFF;float:left;margin:4px 0 4px  4px; padding:2px;width:144px; height: 200px;" class="thumb-wrap" id="{mainImageId}">', 
        '<div style="width: 140px;" class="thumb"><img src="/image?id={mainImageId}&size=140x140"></div>', 
        '<div style="width: 100%; text-align: center; color: #999999;">{artworkTitle}</div>',
        '</div>',
        '</tpl>', 
        '<div class="x-clear"></div>'].join("");
    }-*/;

    private void onSelectionChanged(SelectionChangedEvent<BeanModel> be) {
        Object source = be.getSource();
        Log.debug("source [" + source + "]");
        if (be.getSelection().size() == 0) {
            return;
        }
        final BeanModel model = be.getSelection().get(0);
        Dialog dialog = new Dialog();
        dialog.setSize(920, 800);
        dialog.setAutoHide(true);
        Image image = new Image("/image?id=" + model.get("mainImageId")
                + "&size=920x800");
        dialog.add(image);
        dialog.addText((String) model.get("artworkTitle"));
        dialog.setTitle((String) model.get("artworkTitle"));
        dialog.setBodyStyle("width: 100%; text-align: center; color: #999999;");
        dialog.setHideOnButtonClick(true);
        dialog.setButtons(Dialog.OK);
        dialog.show();
        artworksListView.getSelectionModel().deselectAll();
    }
}
